package com.qifenqian.turbot.net

import com.google.gson.ExclusionStrategy
import com.google.gson.FieldAttributes
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.qifenqian.turbot.config.Constant
import com.qifenqian.turbot.config.TurbotApplication
import com.qifenqian.turbot.util.Lcat
import com.qifenqian.turbot.util.SpUtils
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import org.json.JSONObject
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * @author H
 * @createDate 2018/8/9 10:06
 * @reference
 * @updateDate
 * @description
 * @detail
 * @since
 */
object RetrofitFactory {

    private const val TIMEOUT: Long = 60
    private const val CACHE_SIZE: Long = 10 * 1024 * 1024
    private val CACHE_PATH: String = TurbotApplication.instance().cacheDir.path + "/TurbotCache"

    var TOKEN: String? = SpUtils.getInstance().getString("token", "userInfo")

    private var okHttpClient = OkHttpClient.Builder()
            .retryOnConnectionFailure(true)
            .addInterceptor(object : Interceptor {
                override fun intercept(chain: Interceptor.Chain?): Response {
                    val request = chain!!.request().newBuilder()
                            .addHeader("Content-Type", "application/x-www-form-urlencoded")
//                            .addHeader("Content-Type", "application/json;text/json;text/html;text/javascript;")
//                            .addHeader("Charset", "UTF-8")
//                            .addHeader("Accept", "*/*")
//                            .addHeader("Connection", "keep-alive")
//                            .addHeader("Authorization", "Bearer " + if (Constant.isLogin) TOKEN else "")
                            .build()
                    return chain.proceed(request)
                }
            })
            .addNetworkInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { message: String? ->
                Lcat.i("网络请求 log", message!!)
            }).setLevel(HttpLoggingInterceptor.Level.BODY))
            .connectTimeout(TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(TIMEOUT, TimeUnit.SECONDS)
            .cache(Cache(File(CACHE_PATH), CACHE_SIZE))
            .build()

    fun <T> getRetrofitService(clsService: Class<T>): T {
        return Retrofit.Builder()
                .baseUrl(Constant.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .build()
                .create(clsService)
    }

    fun getUploadService(): TurbotService.UploadService {
        return Retrofit.Builder()
                .baseUrl(Constant.FILE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .build()
                .create(TurbotService.UploadService::class.java)
    }

    fun getRequestBody(map: Map<String, Any>): RequestBody {
        Lcat.i("上传的参数", map)
        val json = GsonBuilder().disableHtmlEscaping().create().toJson(map)
        return RequestBody.create(MediaType.parse("application/json;charset=utf-8"), json)
    }

    fun getRequestBody(jsonObject: JSONObject): RequestBody {
        Lcat.i("上传的参数(含List)", jsonObject)
        return RequestBody.create(MediaType.parse("application/json;charset=utf-8"), jsonObject.toString())
    }

    fun <T> getRequestBody(t: T): RequestBody {
        val gson = ignoreJsonParams("createTime") //不传所有的"createTime"
        Lcat.i("上传的参数(使用实体类)", t)
        return RequestBody.create(MediaType.parse("application/json;charset=utf-8"), gson.toJson(t))
//        return RequestBody.create(MediaType.parse("application/json;charset=utf-8"),  GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(t))
    }

    private fun ignoreJsonParams(vararg params: String): Gson {
        return GsonBuilder().setExclusionStrategies(
                object : ExclusionStrategy {
                    override fun shouldSkipClass(clazz: Class<*>?): Boolean {
                        return false
                    }

                    override fun shouldSkipField(f: FieldAttributes?): Boolean {
                        for (param in params) {
                            if (f!!.name == param) {
                                return true
                            }
                        }
                        return false
                    }
                }).create()
    }

    fun getRequestBody(filePath: String): MultipartBody {
        val builder = MultipartBody.Builder().setType(MultipartBody.FORM)
        builder.addFormDataPart("key", "abc")
        builder.addFormDataPart("file", System.currentTimeMillis().toString() + ".jpg", RequestBody.create(MediaType.parse("multipart/form-data"/*multipart/form-data也可以*/), File(filePath)))
        return builder.build()
    }

}
